package com.zmn.oms.services.impl.changerecord;

import com.vdurmont.emoji.EmojiParser;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.oms.common.constant.OrderDistributeConsts;
import com.zmn.oms.model.dto.changerecord.*;
import com.zmn.oms.model.entity.changerecord.OrderChangeRecord;
import com.zmn.oms.persistence.interfaces.changerecord.OrderChangeRecordDao;
import com.zmn.oms.services.interfaces.changerecord.OrderChangeRecordService;
import io.netty.util.internal.StringUtil;
import io.shardingsphere.api.HintManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 类描述 订单预约，派单等信息修改记录
 *
 * @author xiewenbing
 * @date 2019/11/26 15:20
 */
@Slf4j
@Service
public class OrderChangeRecordServiceImpl implements OrderChangeRecordService {

    @Resource
    private OrderChangeRecordDao orderChangeRecordDao;

    @Override
    public List<OrderChangeRecord> listByOrderIdList(List<Long> orderIdList) {
        try (HintManager hintManager = HintManager.getInstance()) {
            hintManager.setMasterRouteOnly();
            return orderChangeRecordDao.listByOrderIdList(orderIdList);
        }
    }

    /**
     * 添加修改订单预约时间信息记录
     * @param changeDutyTimeDTO
     */
    @Override
    public void updateChangeDutyTimeRecord(ChangeDutyTimeDTO changeDutyTimeDTO){
        if (Objects.isNull(changeDutyTimeDTO)) {
            return;
        }

        Long orderId = changeDutyTimeDTO.getOrderId();
        if (Objects.isNull(orderId)) {
            return;
        }

        if (StringUtils.isNotBlank(changeDutyTimeDTO.getOperatorName())) {// 表情符号转换为字符
            changeDutyTimeDTO.setOperatorName(EmojiParser.parseToAliases(changeDutyTimeDTO.getOperatorName()));
        }

        Date operateTime = new Date();
        // 没有记录，则插入新的记录
        OrderChangeRecord orderChangeRecord = this.getOrderChangeRecord(orderId,changeDutyTimeDTO.getOperatorName(),operateTime);
        if (Objects.isNull(orderChangeRecord)) {
           return;
        }

        if (NumberUtil.isNullOrZero(orderChangeRecord.getFirstDutyOptId())) {

            // 更新第一次和最后一次预约时间修改
            orderChangeRecord.setDutyTimeModifyCount(0);
            orderChangeRecord.setFirstDutyOptId(changeDutyTimeDTO.getOperatorId());
            orderChangeRecord.setFirstDutyOptName(changeDutyTimeDTO.getOperatorName());
            orderChangeRecord.setFirstDutyOptType(changeDutyTimeDTO.getOperatorType());
            orderChangeRecord.setFirstDutyOptTime(operateTime);
            orderChangeRecord.setFirstDutyTime(changeDutyTimeDTO.getDutyTime());

            orderChangeRecordDao.updateOrderFirstDutyTimeChangeRecord(orderChangeRecord);
        } else {

            // 更新最后一次预约时间修改
            orderChangeRecord.setDutyTimeModifyCount(orderChangeRecord.getDutyTimeModifyCount() + 1);
            orderChangeRecord.setLastDutyOptId(changeDutyTimeDTO.getOperatorId());
            orderChangeRecord.setLastDutyOptName(changeDutyTimeDTO.getOperatorName());
            orderChangeRecord.setLastDutyOptType(changeDutyTimeDTO.getOperatorType());
            orderChangeRecord.setLastDutyOptTime(operateTime);
            orderChangeRecord.setLastDutyTime(changeDutyTimeDTO.getDutyTime());

            orderChangeRecordDao.updateOrderLastDutyTimeChangeRecord(orderChangeRecord);
        }

        if (changeDutyTimeDTO.isUpdateOpCount()) {
            OrderChangeRecord updateOrderChangeRecord = new OrderChangeRecord();
            updateOrderChangeRecord.setOrderId(orderId);

            // 预约时间修改次数
            if (Objects.equals(GlobalConsts.OPERATE_USER_TYPE_MASTER, changeDutyTimeDTO.getOperatorType())) {
                updateOrderChangeRecord.setAppDutyTimeModifyCount(Optional.ofNullable(orderChangeRecord.getAppDutyTimeModifyCount()).orElse(0) + 1);
            } else if (Objects.equals(GlobalConsts.OPERATE_USER_TYPE_FACTORY, changeDutyTimeDTO.getOperatorType())) {
                updateOrderChangeRecord.setFcPopDutyTimeModifyCount(Optional.ofNullable(orderChangeRecord.getFcPopDutyTimeModifyCount()).orElse(0) + 1);
            } else if (Objects.equals(GlobalConsts.OPERATE_USER_TYPE_SERVICEPROVIDER, changeDutyTimeDTO.getOperatorType())) {
                updateOrderChangeRecord.setSpPopDutyTimeModifyCount(Optional.ofNullable(orderChangeRecord.getSpPopDutyTimeModifyCount()).orElse(0) + 1);
            } else if (Objects.equals(GlobalConsts.OPERATE_USER_TYPE_STAFF, changeDutyTimeDTO.getOperatorType())) {
                updateOrderChangeRecord.setPlatDutyTimeModifyCount(Optional.ofNullable(orderChangeRecord.getPlatDutyTimeModifyCount()).orElse(0) + 1);
            }

            orderChangeRecordDao.updateDutyTimeModifyCount(updateOrderChangeRecord);
            log.debug("修改改约次数:[{}], updateOrderChangeRecord:[{}]", changeDutyTimeDTO, updateOrderChangeRecord);
        }

    }

    @Override
    public void updateVisitScanTimeRecord(ChangeVisitScanTimeDTO visitScanTimeDTO) {
        if (Objects.isNull(visitScanTimeDTO)) {
            return;
        }

        Long orderId = visitScanTimeDTO.getOrderId();
        if (Objects.isNull(orderId)) {
            return;
        }

        Date operateTime = new Date();
        // 没有记录，则插入新的记录
        OrderChangeRecord orderChangeRecord = this.getOrderChangeRecord(orderId, visitScanTimeDTO.getOperatorName(), operateTime);
        if (Objects.isNull(orderChangeRecord)) {
            return;
        }

        if (Objects.isNull(orderChangeRecord.getFirstVisitScanTime())) {

            // 更新第一次和最后一次预约时间修改
            orderChangeRecord.setFirstVisitScanTime(visitScanTimeDTO.getVisitScanTime());
            orderChangeRecord.setLastVisitScanTime(visitScanTimeDTO.getVisitScanTime());
            orderChangeRecord.setVisitScanOpenId(visitScanTimeDTO.getOpenId());
            orderChangeRecord.setVisitScanUnionId(visitScanTimeDTO.getUnionId());
            orderChangeRecordDao.updateOrderVisitScanTimeChangeRecord(orderChangeRecord);
        } else {

            // 更新最后一次预约时间修改
            orderChangeRecord.setVisitScanOpenId(visitScanTimeDTO.getOpenId());
            orderChangeRecord.setVisitScanUnionId(visitScanTimeDTO.getUnionId());
            orderChangeRecord.setLastVisitScanTime(visitScanTimeDTO.getVisitScanTime());
            orderChangeRecordDao.updateOrderVisitScanTimeChangeRecord(orderChangeRecord);
        }
    }

    @Override
    public void updateMasterImageTimeRecord(ChangeMasterImageTimeDTO masterImageTimeDTO) {
        if (Objects.isNull(masterImageTimeDTO)) {
            return;
        }

        Long orderId = masterImageTimeDTO.getOrderId();
        if (Objects.isNull(orderId)) {
            return;
        }

        Date operateTime = new Date();
        // 没有记录，则插入新的记录
        OrderChangeRecord orderChangeRecord = this.getOrderChangeRecord(orderId, masterImageTimeDTO.getOperatorName(), operateTime);
        if (Objects.isNull(orderChangeRecord)) {
            return;
        }

        if (Objects.isNull(orderChangeRecord.getFirstMasterImageTime())) {

            // 更新第一次和最后一次预约时间修改
            orderChangeRecord.setFirstMasterImageTime(masterImageTimeDTO.getMasterImageTime());
            orderChangeRecord.setLastMasterImageTime(masterImageTimeDTO.getMasterImageTime());
            orderChangeRecordDao.updateOrderMasterImageTimeChangeRecord(orderChangeRecord);
        } else {

            // 更新最后一次预约时间修改
            orderChangeRecord.setLastMasterImageTime(masterImageTimeDTO.getMasterImageTime());
            orderChangeRecordDao.updateOrderMasterImageTimeChangeRecord(orderChangeRecord);
        }
    }

    /**
     * 添加修改订单派单信息记录
     * @param changeDistributeDTO
     */
    @Override
    public void updateChangeDistributeRecord(ChangeDistributeDTO changeDistributeDTO){
        if (Objects.isNull(changeDistributeDTO)) {
            return;
        }

        Long orderId = changeDistributeDTO.getOrderId();
        if (Objects.isNull(orderId)) {
            return;
        }

        Date operateTime = new Date();
        // 没有记录，则插入新的记录
        OrderChangeRecord orderChangeRecord = this.getOrderChangeRecord(orderId, changeDistributeDTO.getOperatorName(), operateTime);
        if (Objects.isNull(orderChangeRecord)) {
            return;
        }

        if (NumberUtil.isNullOrZero(orderChangeRecord.getFirstDistributeOptId())) {

            // 更新第一次和最后一次派单修改
            orderChangeRecord.setDistributeCount(0);
            orderChangeRecord.setFirstDistributeOptId(changeDistributeDTO.getOperatorId());
            orderChangeRecord.setFirstDistributeOptName(changeDistributeDTO.getOperatorName());
            orderChangeRecord.setFirstDistributeOptType(changeDistributeDTO.getOperatorType());
            orderChangeRecord.setFirstDistributeOptTime(operateTime);
            orderChangeRecord.setFirstDistributeTime(changeDistributeDTO.getDistributeTime());
            orderChangeRecord.setFirstDistributeType(changeDistributeDTO.getDistributeType());
            orderChangeRecord.setFirstDistributeRule(changeDistributeDTO.getDistributeRule());
            orderChangeRecord.setFirstDistributeWay(changeDistributeDTO.getDistributeWay());
            orderChangeRecord.setFirstDistributeEntry(changeDistributeDTO.getDistributeEntry());
            if (Objects.nonNull(changeDistributeDTO.getDistributeGrid())) {
                orderChangeRecord.setLastDistributeGrid(changeDistributeDTO.getDistributeGrid());
            }

            orderChangeRecordDao.updateOrderFirstDistributeChangeRecord(orderChangeRecord);
        } else {

            // 更新最后一此派单修改
            orderChangeRecord.setDistributeCount(orderChangeRecord.getDistributeCount() + 1);
            orderChangeRecord.setLastDistributeOptId(changeDistributeDTO.getOperatorId());
            orderChangeRecord.setLastDistributeOptName(changeDistributeDTO.getOperatorName());
            orderChangeRecord.setLastDistributeOptType(changeDistributeDTO.getOperatorType());
            orderChangeRecord.setLastDistributeOptTime(operateTime);
            orderChangeRecord.setLastDistributeTime(changeDistributeDTO.getDistributeTime());
            orderChangeRecord.setLastDistributeType(changeDistributeDTO.getDistributeType());
            orderChangeRecord.setLastDistributeRule(changeDistributeDTO.getDistributeRule());
            orderChangeRecord.setLastDistributeWay(changeDistributeDTO.getDistributeWay());
            orderChangeRecord.setLastDistributeEntry(changeDistributeDTO.getDistributeEntry());
            if (Objects.nonNull(changeDistributeDTO.getDistributeGrid())) {
                orderChangeRecord.setLastDistributeGrid(changeDistributeDTO.getDistributeGrid());
            }
            // 统计后台直接改派次数（如果第一次派单是后台手动派单-不计算）
            if (Objects.equals(OrderDistributeConsts.DISTRIBUTE_ENTRY_ADMIN, changeDistributeDTO.getDistributeEntry())) {
                orderChangeRecord.setRedistributeCount(orderChangeRecord.getRedistributeCount() + 1);
            }

            orderChangeRecordDao.updateOrderLastDistributeChangeRecord(orderChangeRecord);
        }
    }

    @Override
    public void updateChangePrepayAmountRecord(ChangeRecordDTO changeRecordDTO) {
        if (Objects.isNull(changeRecordDTO.getOrderId())) {
            return;
        }

        OrderChangeRecord orderChangeRecord = orderChangeRecordDao.findOrderChangeRecordByKey(changeRecordDTO.getOrderId());
        if (Objects.isNull(orderChangeRecord)) {
            return;
        }

        orderChangeRecord.setLastPrepayAmountOptId(changeRecordDTO.getOperatorId());
        orderChangeRecord.setLastPrepayAmountOptName(changeRecordDTO.getOperatorName());
        orderChangeRecord.setLastPrepayAmountOptType(changeRecordDTO.getOperatorType());
        orderChangeRecord.setLastPrepayAmountOptTime(changeRecordDTO.getOperateTime());

        orderChangeRecordDao.updateOrderPrepayAmountChangeRecord(orderChangeRecord);
    }

    /**
     * 通过订单id查找订单信息修改记录
     * @param orderId
     */
    @Override
    public OrderChangeRecord getChangeRecordByOrderId(Long orderId){
        if (Objects.isNull(orderId)) {
            return null;
        }

        OrderChangeRecord orderChangeRecord = orderChangeRecordDao.findOrderChangeRecordByKey(orderId);
        if (Objects.isNull(orderChangeRecord)) {
            return null;
        }
        if (StringUtils.isNotBlank(orderChangeRecord.getCreater())) {// 表情符号转换为字符
            orderChangeRecord.setCreater(EmojiParser.parseToUnicode(orderChangeRecord.getCreater()));
        }

        return orderChangeRecord;
    }

    @Override
    public void updateLiableMasterRecord(ChangeLiableMasterDTO changeLiableMasterDTO) {
        if (Objects.isNull(changeLiableMasterDTO.getOrderId())) {
            return;
        }
        OrderChangeRecord orderChangeRecord = this.getOrderChangeRecord(changeLiableMasterDTO.getOrderId(), changeLiableMasterDTO.getOperator(), changeLiableMasterDTO.getOperateTime());
        if (Objects.isNull(orderChangeRecord)) {
            orderChangeRecord = new OrderChangeRecord();
        }
        orderChangeRecord.setOrderId(changeLiableMasterDTO.getOrderId());
        orderChangeRecord.setLiableMasterId(changeLiableMasterDTO.getLiableMasterId());
        orderChangeRecord.setLiableMasterName(changeLiableMasterDTO.getLiableMasterName());
        orderChangeRecordDao.updateLiableMasterRecord(orderChangeRecord);
    }

    @Override
    public void updateCancelLiableMasterRecord(ChangeLiableMasterDTO changeLiableMasterDTO) {
        if (Objects.isNull(changeLiableMasterDTO.getOrderId())) {
            return;
        }
        OrderChangeRecord orderChangeRecord = new OrderChangeRecord();
        orderChangeRecord.setOrderId(changeLiableMasterDTO.getOrderId());
        orderChangeRecord.setCancelLiableMasterId(changeLiableMasterDTO.getLiableMasterId());
        orderChangeRecord.setCancelLiableMasterName(changeLiableMasterDTO.getLiableMasterName());
        orderChangeRecordDao.updateCancelLiableMasterRecord(orderChangeRecord);
    }

    @Override
    public void clearCancelLiableAndLiableMasterRecord(Long orderId) {
        if (Objects.isNull(orderId)) {
            return;
        }
        OrderChangeRecord orderChangeRecord = new OrderChangeRecord();
        orderChangeRecord.setOrderId(orderId);
        orderChangeRecordDao.clearCancelLiableAndLiableMasterRecord(orderChangeRecord);
    }

    @Override
    public void updateCancelLiableAndLiableMasterRecord(ChangeLiableMasterDTO changeLiableMasterDTO) {
        if (Objects.isNull(changeLiableMasterDTO.getOrderId())) {
            return;
        }
        OrderChangeRecord orderChangeRecord = this.getOrderChangeRecord(changeLiableMasterDTO.getOrderId(), changeLiableMasterDTO.getOperator(), changeLiableMasterDTO.getOperateTime());
        if (Objects.isNull(orderChangeRecord)) {
            orderChangeRecord = new OrderChangeRecord();
        }
        orderChangeRecord.setOrderId(changeLiableMasterDTO.getOrderId());
        orderChangeRecord.setLiableMasterId(changeLiableMasterDTO.getLiableMasterId());
        orderChangeRecord.setLiableMasterName(changeLiableMasterDTO.getLiableMasterName());
        orderChangeRecord.setCancelLiableMasterId(changeLiableMasterDTO.getCancelLiableMasterId());
        orderChangeRecord.setCancelLiableMasterName(changeLiableMasterDTO.getCancelLiableMasterName());
        orderChangeRecordDao.updateCancelLiableAndLiableMasterRecord(orderChangeRecord);
    }

    @Override
    public void updateChangeServCateg(ChangeServCategDTO changeServCategDTO) {
        if (Objects.isNull(changeServCategDTO.getOrderId())) {
            return;
        }
        OrderChangeRecord orderChangeRecord = this.getOrderChangeRecord(changeServCategDTO.getOrderId(), changeServCategDTO.getOperatorName(), changeServCategDTO.getOperateTime());
        if (Objects.isNull(orderChangeRecord)) {
            orderChangeRecord = new OrderChangeRecord();
        }
        orderChangeRecord.setOrderId(changeServCategDTO.getOrderId());
        orderChangeRecord.setInputServCategId(changeServCategDTO.getInputServCategId());
        orderChangeRecord.setCurrServCategId(changeServCategDTO.getCurrServCategId());
        orderChangeRecordDao.updateServCategRecord(orderChangeRecord);

    }

    @Override
    public OrderChangeRecord getChangeRecordByOrderIdSrcMaster(Long orderId) {
        try (HintManager hintManager = HintManager.getInstance()) {
            hintManager.setMasterRouteOnly();
            if (Objects.isNull(orderId)) {
                return null;
            }

            OrderChangeRecord orderChangeRecord = orderChangeRecordDao.findOrderChangeRecordByKey(orderId);
            if (Objects.isNull(orderChangeRecord)) {
                return null;
            }
            if (StringUtils.isNotBlank(orderChangeRecord.getCreater())) {// 表情符号转换为字符
                orderChangeRecord.setCreater(EmojiParser.parseToUnicode(orderChangeRecord.getCreater()));
            }
            return orderChangeRecord;
        }
    }

    /**
     * 查找或插入一条新的记录，并记录时间和操作人
     * @param orderId
     * @param operator
     * @param operateTime
     * @return OrderChangeRecord
     */
    private OrderChangeRecord getOrderChangeRecord(Long orderId,String operator,Date operateTime) {

        // 参数判断
        if (StringUtil.isNullOrEmpty(operator) || NumberUtil.isNullOrZero(orderId)) {
            return null;
        }

        OrderChangeRecord orderChangeRecord = orderChangeRecordDao.findOrderChangeRecordByKey(orderId);
        if (Objects.nonNull(orderChangeRecord)) {
            orderChangeRecord.setOrderId(orderId);
            orderChangeRecord.setUpdater(operator);
            orderChangeRecord.setUpdateTime(operateTime);

            return orderChangeRecord;
        }

        orderChangeRecord = new OrderChangeRecord();
        orderChangeRecord.setOrderId(orderId);
        orderChangeRecord.setCreater(operator);
        orderChangeRecord.setCreateTime(operateTime);

        orderChangeRecordDao.insertOrderWorkChangeRecord(orderChangeRecord);

        return orderChangeRecord;
    }

    @Override
    public void clearVisitInfo(Long orderId, Long workId) {

        // 参数判断
        if (NumberUtil.isNullOrZero(orderId)) {
            return;
        }

        OrderChangeRecord orderChangeRecord = orderChangeRecordDao.findOrderChangeRecordByKey(orderId);
        if (Objects.isNull(orderChangeRecord)) {
            return;
        }

        orderChangeRecord = new OrderChangeRecord();
        orderChangeRecord.setOrderId(orderId);
        orderChangeRecord.setVisitScanOpenId("");
        orderChangeRecord.setVisitScanUnionId("");

        orderChangeRecordDao.clearOrderVisitScanTimeChangeRecord(orderChangeRecord);
    }
}
